import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * trieda na udrzovanie outputovych formatov
 * @author cerko
 *
 */
public class FormatList {
	
	//typy ake obsahuje tento format eg: author, title , year
	private Set<String> types;
	/*
	 * samotny format spraveny ako spajany zoznam z dvoch typov nodes,
	 *  jedny su cisto na text druhe na typy ktorym este treba priradit hodnotu
	 */
	private ArrayList<Node> Format;
	
	public FormatList(){
		Format = new ArrayList<>();
		types = new HashSet<String>();
	}
	
	/**
	 * podla zaciatocneho znaku priradi parameter ako typenode alebo textnode
	 * @param text - text ktory chceme pridat
	 */
	public void add(String text){
		if (text.charAt(0) == '@')
			addType(text);
		else
			addText(text);
	}
	
	/**
	 * pridate textNode
	 * @param text - text ktory chceme pridat
	 */
	public void addText(String text){
		Format.add(new TextNode(text));
	}
	
	/**
	 * prida typeNode
	 * @param type - typ ktory chceme pridat
	 */
	public void addType(String type){
		types.add(type.replace("@", ""));
		Format.add(new TypeNode(type.replace("@", "")));
	}
	
	/*
	public double computeMatch(Data data){
		int hits = 0;
		Set<String> keys = data.getValues().keySet();
		
		if (types.equals(keys)){
			return 1;
		}
		else {
			for (String type : types){
				if (keys.contains(type)){
					hits++;
				}
			}
		}
		int divider = (types.size() > keys.size() ? types.size() : keys.size());
		return hits / divider;
		
		//return hits / keys.size();
	}
	*/
	
	/**
	 * skontroluje ci sa zhoduju typy referencie ktoru chceme naformatovat s tymto formatListom
	 * @param inputTypes - vstupne typy ktore skotrolujeme ci sa zhoduju s typmi formatListu
	 * @return - true ak je zhoda inak false
	 */
	public boolean matchesTypes(Set<String> inputTypes){
		int hits = 0;

		for (String type : types){
			if (inputTypes.contains(type)){
				hits++;
			}
		}
		
		int divider = (types.size() > inputTypes.size() ? types.size() : inputTypes.size());
		return (hits / divider) == 1;
		//return (hits / types.size()) == 1;
	}
	
	public Set<String> getTypes() {
		return types;
	}

	public void setTypes(Set<String> types) {
		this.types = types;
	}

	public void setFormat(ArrayList<Node> format) {
		Format = format;
	}
	
	public ArrayList<Node> getFormat(){
		return Format;
	}
	
	public int getSize(){
		return Format.size();
	}
	
	@Override
	public String toString(){
		String res = "[types : " + types.toString() + "]  [list : ";
		for (Node node : Format){
			res += node.getInfo();
		}
		res += "]";
		return res;
	}
	
	
	
}
